package com.travelsmart.client.apresentacao.view;


import java.util.Date;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;


import com.google.gwt.user.client.ui.VerticalPanel;

import com.travelsmart.client.apresentacao.controller.CommandController;
import com.travelsmart.client.apresentacao.controller.Observer;

import com.travelsmart.client.apresentacao.i18n.I18nMessages;
import com.travelsmart.client.apresentacao.view.subview.ViewCartao;
import com.travelsmart.client.apresentacao.view.subview.ViewDadosRoom;
import com.travelsmart.client.apresentacao.view.subview.ViewEnderecoCombranca;
import com.travelsmart.client.apresentacao.view.subview.ViewListReservaQuarto;
import com.travelsmart.client.apresentacao.widget.FormButton;
import com.travelsmart.client.apresentacao.widget.FormWidget;
import com.travelsmart.client.bean.to.FilterPesquisaHotel;
import com.travelsmart.client.bean.to.HotelTO;
import com.travelsmart.client.bean.to.ReservaHotelTO;
import com.travelsmart.client.bean.to.QuartoTO;
/**
 * Monta a GUI que realiza a construção da ReservaHotelTO.
 * 
 * Sempre que o usuário clicar no botão reserva irá ocorrer:
 * 1- O view reconhece que houve uma ação na GUI - clique de botão reserva - usando uma classe ClickHandler criadas para esta finalidade;
 * 2- Os views realizam a validação de todos os dados fornecidos pelo usuário
 * 
 * se validação ok
 * 3a- O view armazena os dados fornecidos pelo usuário em um objeto ReservaHotelTO
 * 4a -O view chama o método apropriado no controller. Em resposta a uma ação do usuário na GUI, o controller executa um método 
 * 5a- O controller acessa o model de acordo com a solicitação do usuário executada pela chamada ao método referido no passo 4a.
 * 6a- Validação dos dados na camada model (regras de negócio)
 * 		se validação ok 
 * 		7c- Se o model for alterado ele notifica os ouvintes ( OBSERVADORES interessados) - neste caso o view.
 * 		se validação não ok
 * 		7d- notifica os ouvintes ( OBSERVADORES interessados) - sobre o problema (neste caso, tbem é o view).
 *  
 * 
 * se validação não ok
 *  3b- exibe mensagem de erro p/ usuário
 * @author arthur
 *
 */
public class ViewCriaReservaHotel extends BaseView implements Observer {

	private ReservaHotelTO reserva;
	private CommandController<ReservaHotelTO> handler = null;
	private final VerticalPanel vPanelViewReservaHotel = new VerticalPanel();
	private final ViewListReservaQuarto viewListQuarto = new ViewListReservaQuarto();
	//# INICIO - EXERC. 6
	private final ViewCartao viewCartao = new ViewCartao(new HTML(I18nMessages.INSTANCE.detalhes_pagamento()));
	//FIM - EXERC. 6 #/
	private final ViewEnderecoCombranca viewEnderecoCombranca = new ViewEnderecoCombranca(new HTML(I18nMessages.INSTANCE.endereco_de_cobranca()));
	private final ViewDadosRoom viewDadosRoom = new ViewDadosRoom(new HTML(I18nMessages.INSTANCE.detalhes_quarto()));

	public ViewCriaReservaHotel(CommandController<ReservaHotelTO> handler) {
		super(new HTML(I18nMessages.INSTANCE.reserva()));
		this.handler = handler;
		initWidget(vPanelViewReservaHotel);
	}


	public void exec(final QuartoTO quarto) {
		final HorizontalPanel hp1 = new HorizontalPanel();
		hp1.setWidth("100%");
		//# INICIO - EXERC. 6
		viewCartao.exec(); 
		hp1.add(viewCartao);
		//FIM - EXERC. 6 #/
		
		// INICIO - EXERC. 3
		vPanelViewReservaHotel.clear();
		vPanelViewReservaHotel.add(viewDadosRoom);
		vPanelViewReservaHotel.add(viewListQuarto);
		viewEnderecoCombranca.exec();
		hp1.add(viewEnderecoCombranca);
		vPanelViewReservaHotel.add(hp1);
		vPanelViewReservaHotel.add(new FormButton(
				"<span id='form_button_reserva'>" + I18nMessages.INSTANCE.reserva() + "</span>", null, 
				new FormWidget.HandlerValidation<String>() {
					@Override
					public boolean handle(String valor) {
						boolean retorno = true;
						
						if (retorno = validar()) {
							handler.handleSuccess(criarReservaHotelTO(quarto));
						}
						
						return retorno;
					}
				}));
		// FIM - EXERC. 3
	}
	
	private ReservaHotelTO criarReservaHotelTO(final QuartoTO quarto) {
		//# INICIO - EXERC. 6
		reserva.setCartao(viewCartao.criarCartaoCreditoTO());
		//FIM - EXERC. 6 #/
		reserva.setData(new Date());
		reserva.setDiaria(quarto.getPrecoString());
		//reserva.setDias("");
		reserva.setEnderecoPagamento(viewEnderecoCombranca
				.criarEnderecoPagamentoTO());
		reserva.setQuartos(viewListQuarto.criarListReservaQuartoTO(quarto));
		return reserva;
	}

	private boolean validar() {
		boolean retorno = viewListQuarto.validar();

		if (retorno) {
			
			if (retorno = viewEnderecoCombranca.validar()) {
				//# INICIO - EXERC. 6
				retorno = viewCartao.validar();
				//FIM - EXERC. 6 #/
			}
			
		}
		return retorno;
				
	}
	
	
	

	@Override
	public void update(Object arg) {
		// INICIO - EXERC. 3
		if (arg instanceof HotelTO) {
			HotelTO hotelSelecionado = (HotelTO) arg;
			reserva.setHotel(hotelSelecionado);
		} else if (arg instanceof FilterPesquisaHotel) {
			if (reserva == null) {
				reserva = new ReservaHotelTO();
			}
			
			FilterPesquisaHotel filter = (FilterPesquisaHotel) arg;
			viewListQuarto.exec(filter);
			reserva.setDataEntrada(filter.getEntrada());
			reserva.setDataSaida(filter.getSaida());
		} else if (arg instanceof QuartoTO) {
			QuartoTO quarto = (QuartoTO) arg;
			exec(quarto);
		}
		// FIM - EXERC. 3
	}

	public ViewDadosRoom getViewDadosRoom() {
		return viewDadosRoom;
	}
	
	
	
	
}
